package org.doubango.FrCall.Utils.json;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.doubango.FrCall.Utils.LogDebugger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Model binder class. This class can bind json string to model, to model list,
 * or to map.
 * 
 */
public class ObjectMapper {

	/**
	 * bind json string to model.
	 * 
	 * @param <T>
	 *            T
	 * @param content
	 *            json string
	 * @param cls
	 *            Class<T>
	 * @return <T>
	 */
	public static <T> T bindModel(String content, Class<T> cls) {
		try {
			JSONObject mjson = new JSONObject(content);
			try {
				T instance = cls.newInstance();
				Iterator it = mjson.keys();
				while (it.hasNext()) {
					String next = it.next().toString();
					ModelReflector.setProperty(instance, next, mjson.get(next)
							.toString());
				}
				return instance;
			} catch (IllegalAccessException e) {
				LogDebugger.exception(e.getMessage());
			} catch (InstantiationException e) {
				LogDebugger.exception(e.getMessage());
			}
		} catch (JSONException e) {
			LogDebugger.exception(e.getMessage());
		}

		return null;
	}

	/**
	 * bind json string to model list.
	 * 
	 * @param <T>
	 *            T
	 * @param content
	 *            json string
	 * @param cls
	 *            Class<T>
	 * @return <T> List<T>
	 */
	public static <T> List<T> bindModelList(String content, Class<T> cls) {
		try {
			JSONArray mjson = new JSONArray(content);
			List<T> list = new ArrayList<T>();
			for (int i = 0; i < mjson.length(); i++) {
				T t = bindModel(mjson.get(i).toString(), cls);
				list.add(t);
			}
			return list;
		} catch (JSONException e) {
			LogDebugger.exception(e.getMessage());
		}
		return null;
	}
	
	/**
	 * bind json string to model list.
	 * 
	 * @param <T>
	 *            T
	 * @param content
	 *            json string
	 * @param cls
	 *            Class<T>
	 * @return <T> List<T>
	 */
	public static <T> List<List<T>> bindModelListList(String content, Class<T> cls) {
		try {
			JSONArray mjson = new JSONArray(content);
			List<List<T>> list = new ArrayList<List<T>>();
			for (int i = 0; i < mjson.length(); i++) {
				List<T> t = bindModelList(mjson.get(i).toString(), cls);
				list.add(t);
			}
			return list;
		} catch (JSONException e) {
			LogDebugger.exception(e.getMessage());
		}
		return null;
	}

	/**
	 * bin json string to map object.
	 * 
	 * @param content
	 *            json string
	 * @return map object.
	 */
	public static Map bindDataToMap(String content) {
		try {
			JSONObject mjosn = new JSONObject(content);
			Map<String, String> map = new HashMap<String, String>();
			map.put("code", mjosn.getString("code"));
			map.put("message", mjosn.getString("message"));
			map.put("data", mjosn.getString("data"));
			return map;
		} catch (JSONException e) {
			LogDebugger.exception(e.getMessage());
		}
		return null;
	}
}
